﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing.Design;
using EzDeploy.Core.Design.Editor;

namespace EzDeploy.Core
{
    public class Project
    {
        private const int _ProjectVersion = 1;

        string _assemblyFile;
        private string _strongnameKeyFile;
        bool _assemblyHasPublicKey;
        string _runtimeVersion;
        string _deployedDirectory;
        bool _overWriteFile;
        bool _hideExcludedAssembly = true;

        Dictionary<string, string> _attributes;

        ObservableCollection<ExludedItem> _excluded;
        Dictionary<string, DeploymentType> _assemblies;

        [Browsable(false)]
        public Dictionary<string, string> Attributes
        {
            get
            {
                if (_attributes == null)
                    _attributes = new Dictionary<string, string>();
                return _attributes;
            }
        }

        [Browsable(false)]
        public int ProjectVersion
        {
            get
            {
                return _ProjectVersion;
            }
        }

        [Editor(typeof(StrongNameKeyFileNameEditor), typeof(UITypeEditor))]
        [Description("Strong Name Key")]
        [Category("Assembly"), DisplayName("2. Strong Name Key")]
        public string StrongnameKeyFile
        {
            get { return _strongnameKeyFile; }
            set { _strongnameKeyFile = value; }
        }

        [Description(".NET Runtime Version.")]
        [Category("Assembly"), DisplayName("3. Runtime")]
        [ReadOnly(true)]
        public string RuntimeVersion
        {
            get { return _runtimeVersion; }
            set { _runtimeVersion = value; }
        }

        [Editor(typeof(AssemblyFileNameEditor), typeof(UITypeEditor))]
        [Category("Assembly"), DisplayName("1. FileName")]
        public string AssemblyFile
        {
            get { return _assemblyFile; }
            set
            {
                bool valueChanged = value != _assemblyFile;
                _assemblyFile = value;

                if (valueChanged)
                    this.OnChanged(ProjectProperty.AssemblyFile);
            }
        }

        [Editor(typeof(DeployedDirectoryNameEditor), typeof(UITypeEditor))]
        [DisplayName("1. Deployed Directory")]
        [Category("Settings")]
        public string DeployedDirectory
        {
            get
            {
                return _deployedDirectory;
            }
            set
            {
                _deployedDirectory = value;
            }
        }

        [DisplayName("2. Overwrite File")]
        [Category("Settings")]
        public bool OverWriteFile
        {
            get { return _overWriteFile; }
            set { _overWriteFile = value; }
        }

        [DisplayName("3. Excluded Pattern")]
        [Category("Settings")]
        public ObservableCollection<ExludedItem> Excluded
        {
            get
            {
                if (_excluded == null)
                {
                    _excluded = new ObservableCollection<ExludedItem>();
                    _excluded.CollectionChanged += Excluded_CollectionChanged;
                }
                return _excluded;
            }
        }

        [Category("Settings")]
        [DisplayName("4. Hide Excluded Assembly")]
        public bool HideExcludedAssembly
        {
            get
            {
                return _hideExcludedAssembly;
            }
            set
            {
                bool changed = value != _hideExcludedAssembly;
                _hideExcludedAssembly = value;

                if (changed)
                    this.OnChanged(ProjectProperty.HideExcludedAssembly);
            }
        }

        [Browsable(false)]
        public Dictionary<string, DeploymentType> Assemblies
        {
            get
            {
                if (_assemblies == null)
                    _assemblies = new Dictionary<string, DeploymentType>();
                return _assemblies;
            }
        }

        private void Excluded_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                default:
                    this.OnChanged(ProjectProperty.Excluded);
                    break;
            }
        }

        private void OnChanged(ProjectProperty property)
        {
            var ev = this.Changed;
            if (ev != null)
                ev(this, property);
        }

        public event ProjectPropertyChangedEventHandler Changed;

        [ReadOnly(true)]
        [Browsable(false)]
        public bool AssemblyHasPublicKey
        {
            get
            {
                return _assemblyHasPublicKey;
            }
            set
            {
                _assemblyHasPublicKey = value;
            }
        }
    }
}
